#ifndef MDTX_USE_RCPPARMADILLO
#define MDTX_USE_RCPPARMADILLO
#endif

#include <RcppArmadillo.h>
using namespace Rcpp;

#include "mdtx-online/indicator/indicator_type_ma.h"
using namespace mdtx::online;

#include "indi_common.h"

using cma_ = indi1<indicator::cma>;

//' Cumulative moving average
//'
//' @param x Numeric vector to average over
//' @return Numeric vector
//' @export
// [[Rcpp::export(rng = false)]]
NumericVector cma(NumericVector x)
{
    auto c = cma_::create_t();
    return cma_::run_t(c, x);
}

// [[Rcpp::export(rng = false)]]
SEXP cma_new()
{
    return cma_::create();
}

// [[Rcpp::export(rng = false)]]
NumericVector cma_run(SEXP ptr, NumericVector x)
{
    return cma_::run(ptr, x);
}

using sma_ = indi1<indicator::sma>;

//' Simple moving average
//'
//' @param x Numeric vector to average over
//' @param period Period of rolling window
//' @return Numeric vector
//' @export
// [[Rcpp::export(rng = false)]]
NumericVector sma(NumericVector x, int period)
{
    auto c = sma_::create_t(period);
    return sma_::run_t(c, x);
}

// [[Rcpp::export(rng = false)]]
SEXP sma_new(int period)
{
    return sma_::create(period);
}

// [[Rcpp::export(rng = false)]]
NumericVector sma_run(SEXP ptr, NumericVector x)
{
    return sma_::run(ptr, x);
}

using tma_ = indi1<indicator::tma>;

//' Triangular moving average
//'
//' @param x Numeric vector to average over
//' @param period Period of rolling window
//' @return Numeric vector
//' @export
// [[Rcpp::export(rng = false)]]
NumericVector tma(NumericVector x, int period)
{
    auto c = tma_::create_t(period);
    return tma_::run_t(c, x);
}

// [[Rcpp::export(rng = false)]]
SEXP tma_new(int period)
{
    return tma_::create(period);
}

// [[Rcpp::export(rng = false)]]
NumericVector tma_run(SEXP ptr, NumericVector x)
{
    return tma_::run(ptr, x);
}

using wma_ = indi1<indicator::wma>;

//' Weighted (linear) moving average
//'
//' @param x Numeric vector to average over
//' @param period Period of rolling window
//' @return Numeric vector
//' @export
// [[Rcpp::export(rng = false)]]
NumericVector wma(NumericVector x, int period)
{
    auto c = wma_::create_t(period);
    return wma_::run_t(c, x);
}

// [[Rcpp::export(rng = false)]]
SEXP wma_new(int period)
{
    return wma_::create(period);
}

// [[Rcpp::export(rng = false)]]
NumericVector wma_run(SEXP ptr, NumericVector x)
{
    return wma_::run(ptr, x);
}

using hma_ = indi1<indicator::hma>;

//' Hull moving average
//'
//' @param x Numeric vector to average over
//' @param period Period of rolling window
//' @return Numeric vector
//' @export
// [[Rcpp::export(rng = false)]]
NumericVector hma(NumericVector x, int period)
{
    auto c = hma_::create_t(period);
    return hma_::run_t(c, x);
}

// [[Rcpp::export(rng = false)]]
SEXP hma_new(int period)
{
    return hma_::create(period);
}

// [[Rcpp::export(rng = false)]]
NumericVector hma_run(SEXP ptr, NumericVector x)
{
    return hma_::run(ptr, x);
}

using ema_ = indi1<indicator::ema>;

//' Exponential moving average
//'
//' @param x Numeric vector to average over
//' @param period Period of rolling window
//' @return Numeric vector
//' @export
// [[Rcpp::export(rng = false)]]
NumericVector ema(NumericVector x, int period)
{
    auto c = ema_::create_t(period);
    return ema_::run_t(c, x);
}

// [[Rcpp::export(rng = false)]]
SEXP ema_new(int period)
{
    return ema_::create(period);
}

// [[Rcpp::export(rng = false)]]
NumericVector ema_run(SEXP ptr, NumericVector x)
{
    return ema_::run(ptr, x);
}

using dema_ = indi1<indicator::dema>;

//' Double EMA
//'
//' @param x Numeric vector to average over
//' @param period Period of rolling window
//' @return Numeric vector
//' @export
// [[Rcpp::export(rng = false)]]
NumericVector dema(NumericVector x, int period)
{
    auto c = dema_::create_t(period);
    return dema_::run_t(c, x);
}

// [[Rcpp::export(rng = false)]]
SEXP dema_new(int period)
{
    return dema_::create(period);
}

// [[Rcpp::export(rng = false)]]
NumericVector dema_run(SEXP ptr, NumericVector x)
{
    return dema_::run(ptr, x);
}

using tema_ = indi1<indicator::tema>;

//' Triple EMA
//'
//' @param x Numeric vector to average over
//' @param period Period of rolling window
//' @return Numeric vector
//' @export
// [[Rcpp::export(rng = false)]]
NumericVector tema(NumericVector x, int period)
{
    auto c = tema_::create_t(period);
    return tema_::run_t(c, x);
}

// [[Rcpp::export(rng = false)]]
SEXP tema_new(int period)
{
    return tema_::create(period);
}

// [[Rcpp::export(rng = false)]]
NumericVector tema_run(SEXP ptr, NumericVector x)
{
    return tema_::run(ptr, x);
}

using t3ma_ = indi1<indicator::t3ma>;

//' T3 EMA
//'
//' @param x Numeric vector to average over
//' @param period Period of rolling window
//' @return Numeric vector
//' @export
// [[Rcpp::export(rng = false)]]
NumericVector t3ma(NumericVector x, int period)
{
    auto c = t3ma_::create_t(period);
    return t3ma_::run_t(c, x);
}

// [[Rcpp::export(rng = false)]]
SEXP t3ma_new(int period)
{
    return t3ma_::create(period);
}

// [[Rcpp::export(rng = false)]]
NumericVector t3ma_run(SEXP ptr, NumericVector x)
{
    return t3ma_::run(ptr, x);
}

using ewma_ = indi1<indicator::ewma>;

//' Windowed EMA
//'
//' @param x Numeric vector to average over
//' @param period Period of rolling window
//' @return Numeric vector
//' @export
// [[Rcpp::export(rng = false)]]
NumericVector ewma(NumericVector x, int period)
{
    auto c = ewma_::create_t(period);
    return ewma_::run_t(c, x);
}

// [[Rcpp::export(rng = false)]]
SEXP ewma_new(int period)
{
    return ewma_::create(period);
}

// [[Rcpp::export(rng = false)]]
NumericVector ewma_run(SEXP ptr, NumericVector x)
{
    return ewma_::run(ptr, x);
}

using zlema_ = indi1<indicator::zlema>;

//' Zero-lag EMA
//'
//' @param x Numeric vector to average over
//' @param period Period of rolling window
//' @return Numeric vector
//' @export
// [[Rcpp::export(rng = false)]]
NumericVector zlema(NumericVector x, int period)
{
    auto c = zlema_::create_t(period);
    return zlema_::run_t(c, x);
}

// [[Rcpp::export(rng = false)]]
SEXP zlema_new(int period)
{
    return zlema_::create(period);
}

// [[Rcpp::export(rng = false)]]
NumericVector zlema_run(SEXP ptr, NumericVector x)
{
    return zlema_::run(ptr, x);
}

using wilders_ = indi1<indicator::wilders>;

//' Wilders moving average
//'
//' @param x Numeric vector to average over
//' @param period Period of rolling window
//' @return Numeric vector
//' @export
// [[Rcpp::export(rng = false)]]
NumericVector wilders(NumericVector x, int period)
{
    auto c = wilders_::create_t(period);
    return wilders_::run_t(c, x);
}

// [[Rcpp::export(rng = false)]]
SEXP wilders_new(int period)
{
    return wilders_::create(period);
}

// [[Rcpp::export(rng = false)]]
NumericVector wilders_run(SEXP ptr, NumericVector x)
{
    return wilders_::run(ptr, x);
}

using vwma_ = indi1<indicator::vwma>;

//' Volume weighted moving average
//'
//' @param price Numeric vector of price
//' @param volume Numeric vector of volume
//' @param period Period of rolling window
//' @return Numeric vector
//' @export
// [[Rcpp::export(rng = false)]]
NumericVector vwma(NumericVector price, NumericVector volume, int period)
{
    auto c = vwma_::create_t(period);
    return vwma_::run_t(c, price, volume);
}

// [[Rcpp::export(rng = false)]]
SEXP vwma_new(int period)
{
    return vwma_::create(period);
}

// [[Rcpp::export(rng = false)]]
NumericVector vwma_run(SEXP ptr, NumericVector price, NumericVector volume)
{
    return vwma_::run(ptr, price, volume);
}

using evwma_ = indi1<indicator::evwma>;

//' Elastic volume weighted moving average
//'
//' @param price Numeric vector of price
//' @param volume Numeric vector of volume
//' @param period Period of rolling window
//' @return Numeric vector
//' @export
// [[Rcpp::export(rng = false)]]
NumericVector evwma(NumericVector price, NumericVector volume, int period)
{
    auto c = evwma_::create_t(period);
    return evwma_::run_t(c, price, volume);
}

// [[Rcpp::export(rng = false)]]
SEXP evwma_new(int period)
{
    return evwma_::create(period);
}

// [[Rcpp::export(rng = false)]]
NumericVector evwma_run(SEXP ptr, NumericVector price, NumericVector volume)
{
    return evwma_::run(ptr, price, volume);
}

using vidya_ = indi1<indicator::vidya>;

//' Variable index dynamic average
//'
//' @param x Numeric vector to average over
//' @param fast_period Fast period
//' @param slow_period Slow period
//' @param fa Smoothing factor, usually 0.2
//' @return Numeric vector
//' @export
// [[Rcpp::export(rng = false)]]
NumericVector vidya(NumericVector x, int fast_period, int slow_period, double fa = 0.2)
{
    auto c = vidya_::create_t(fast_period, slow_period, fa);
    return vidya_::run_t(c, x);
}

// [[Rcpp::export(rng = false)]]
SEXP vidya_new(int fast_period, int slow_period, double fa = 0.2)
{
    return vidya_::create(fast_period, slow_period, fa);
}

// [[Rcpp::export(rng = false)]]
NumericVector vidya_run(SEXP ptr, NumericVector x)
{
    return vidya_::run(ptr, x);
}

using kama_ = indi1<indicator::kama>;

//' Kaufman adaptive moving average
//'
//' @param x Numeric vector to average over
//' @param fast_period Fast period, usually 2
//' @param slow_period Slow period, usually 30
//' @return Numeric vector
//' @export
// [[Rcpp::export(rng = false)]]
NumericVector kama(NumericVector x, int fast_period = 2, int slow_period = 30)
{
    auto c = kama_::create_t(fast_period, slow_period);
    return kama_::run_t(c, x);
}

// [[Rcpp::export(rng = false)]]
SEXP kama_new(int fast_period = 2, int slow_period = 30)
{
    return kama_::create(fast_period, slow_period);
}

// [[Rcpp::export(rng = false)]]
NumericVector kama_run(SEXP ptr, NumericVector x)
{
    return kama_::run(ptr, x);
}

using mae_ = indi1<indicator::mae>;

//' Mean average error
//'
//' Warning: O(N) algorithm
//'
//' @param x Numeric vector
//' @param period Period of rolling window
//' @return Numeric vector
//' @export
// [[Rcpp::export(rng = false)]]
NumericVector mae(NumericVector x, int period)
{
    auto c = mae_::create_t(period);
    return mae_::run_t(c, x);
}

// [[Rcpp::export(rng = false)]]
SEXP mae_new(int period)
{
    return mae_::create(period);
}

// [[Rcpp::export(rng = false)]]
NumericVector mae_run(SEXP ptr, NumericVector x)
{
    return mae_::run(ptr, x);
}

using trix_ = indi1<indicator::trix>;

//' TRIX
//'
//' @param x Numeric vector
//' @param period Period of rolling window
//' @return Numeric vector
//' @export
// [[Rcpp::export(rng = false)]]
NumericVector trix(NumericVector x, int period)
{
    auto c = trix_::create_t(period);
    return trix_::run_t(c, x);
}

// [[Rcpp::export(rng = false)]]
SEXP trix_new(int period)
{
    return trix_::create(period);
}

// [[Rcpp::export(rng = false)]]
NumericVector trix_run(SEXP ptr, NumericVector x)
{
    return trix_::run(ptr, x);
}
